DIRS := calc dev dev_enum dev_struct doc elm_core erltodo typed_libs

OTP_RELEASE := $(shell erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell)


build: $(if $(USE_STERLANG_DAEMON),build-daemon,build-native)


build-native:
	../tools/rebar3 compile

build-jar:
	USE_STERLANG_JAR=true ../tools/rebar3 compile

build-daemon:
	cd ../sterlang && sbtn sterlangd
	ERL_FLAGS="-args_file dev.vm.args" ../tools/rebar3 compile


# we depend on `clean` because that will force rebar to copy over the priv dir containing
# sterlang.jar
build-sterlang-jar: clean
	make -C ../sterlang


test: test-ir test-beam test-interop test-examples test-others


# test using sterlang jar file. This is a good balance for erltc CI on each push
# because it is closer what the users will use than sterlangd (daemon) and not as slow to build as a native binary
test-jar: build-sterlang-jar
	USE_STERLANG_JAR=true make -C . test

# test using sterlang running as a daemon. This is the main mode used during sterlang development
test-daemon:
	USE_STERLANG_DAEMON=true make -C . test

# test using a native sterlang binary.
test-native: test


clean:
	rm -rf _build
	find . -name "*.els" -delete || true

test-ir: $(DIRS:%=test-ir/%)

clean-ir:
	test -d _build && find _build -type d -name build | xargs rm -rf || true

ifeq ($(OTP_RELEASE),"23")
test-beam: $(DIRS:%=test-beam/%)
else
# there's a crash in ../tools/disassemble.escript on R24
test-beam:
	@echo
	@echo SKIPPING test-beam tests for the currently installed OTP release $(OTP_RELEASE). They do not seem to work on R24.
	@echo
endif

ir: clean-ir build

# The generated .erl files are not actually used in compilation
# but are there for humans to read. Not actually "ir"
test-ir/%: ir
	@# only include .erl files
	diff -r -x sterlang -x '*.defs' -x '*.etf' -x '*.D' -x '*.els' _build/default/lib/$*/build $*/ir-spec

# test `erlt --------> beam -> disassembly`
# matches `erlt -> erl -> beam -> disassembly`
test-beam/%: ir
	rm -rf _build/default/lib/$*/test_ouptput
	mkdir -p _build/default/lib/$*/test_output/from_erl
	mkdir -p _build/default/lib/$*/test_output/from_beam
	../tools/disassemble.escript --beam _build/default/lib/$*/ebin _build/default/lib/$*/test_output/from_beam
	@# this is annoying hard-coding, but we need to exclude files generated by rebar's classic erlang and yrl+xrl compilers
	@# because they won't have corresponding .erls in the build directory. We'll need to do the same for beams generated from .erls in future
	@# Note: we ignore t_* files because these come from the built-ins (see ../erltc/built_ins/README.md
	rm -f _build/default/lib/$*/test_output/from_beam/*_lexer.dis _build/default/lib/$*/test_output/from_beam/*_parser.dis
	../tools/disassemble.escript --erl _build/default/lib/$*/build _build/default/lib/$*/test_output/from_erl
	diff -r _build/default/lib/$*/test_output/from_beam _build/default/lib/$*/test_output/from_erl -x t_*

update-ir-spec/%: ir
	@rm -rf $*/ir-spec
	@mkdir $*/ir-spec
	cp _build/default/lib/$*/build/*.erl $*/ir-spec

update-ir-spec: $(DIRS:%=update-ir-spec/%)

test-others:
	$(MAKE) -C checks/src test

test-interop: build
	# test that we are not removing beams generated from classic rebar compilers
	@stat _build/default/lib/calc/ebin/calc_lexer.beam &> /dev/null
	@stat _build/default/lib/calc/ebin/calc_parser.beam &> /dev/null && echo ok

test-examples:
	rm -rf ../examples/_build
	cd ../examples && ../tools/rebar3 compile


.PHONY: build build-ci build-dev build-sterlang-jar clean ir update-ir-spec \
		test-native test-jar test-beam test-interop test-ir test-examples
